﻿using System;
using WiMo.Games.Drawables;
using System.Drawing;
using System.Drawing.Imaging;

namespace WiMo.Games.OpenGLDisplay.Drawables
{
    public class SpriteText : SpriteTextBase
    {
        public SpriteText()
        {
            BackgroundColor = Color.Transparent;
        }

        public override void Render(IDisplay display)
        {
            display.Render(this);
        }

        public override void Dispose()
        {
            var font = Font.FontInformation as IDisposable;
            if (font != null)
                font.Dispose();

            Font.FontInformation = null;
        }

        private Point GetOrigin(Origin origin, PointF original, Size size)
        {
            var point = new Point();

            if (origin == Origin.TopLeft)
                point = new Point(Convert.ToInt32(original.X), Convert.ToInt32(original.Y));
            else
                point = new Point(Convert.ToInt32(original.X - size.Width / 2), Convert.ToInt32(original.Y - size.Height / 2));

            return point;
        }

        private float GetScaledFontSize(int dpi, float fontSize)
        {
            switch (dpi)
            {
                case 96:
                    if (Scale.X != 1.0f && Scale.Y != 1.0f)
                        return fontSize * Scale.X;
                    break;
                case 128:
                    return fontSize / 1.5f;
                case 192:
                    if (Scale.X != 2.0f && Scale.Y != 2.0f)
                        return fontSize / 1.5f;
                    break;
            }

            return fontSize;
        }

        public Font CreateFont(int dpi)
        {
            var fontStyle = FontStyle.Regular;
            if (Font.Bold) fontStyle |= FontStyle.Bold;
            if (Font.Italics) fontStyle |= FontStyle.Italic;
            if (Font.Underline) fontStyle |= FontStyle.Underline;
            if (Font.StrikeThrough) fontStyle |= FontStyle.Strikeout;

            return new Font(Font.Name, Convert.ToSingle(GetScaledFontSize(dpi, Font.Size)), fontStyle);
        }


        public Bitmap CreateImage(Graphics graphics)
        {
            var textSize = graphics.MeasureString(Text, Font.FontInformation as Font);
            //Scaling for font size happens automatically so if we want to set the auto size
            //for the text, we need to divided by current scale.
            if (Size == Size.Zero)
                UnscaledSize = new Size(Convert.ToSingle(textSize.Width) / Scale.X, Convert.ToSingle(textSize.Height) / Scale.Y);
                
            var image = new Bitmap(Size.Width, Size.Height);
            DrawInformation = image;
            var bmGraphics = Graphics.FromImage(DrawInformation as Bitmap);

            var sb = new SolidBrush(ForeColor.ToDrawingColor());

            if (BackgroundColor == Color.Transparent)
                ColorKey = ForeColor.GetInverted();
            else            
                ColorKey = Color.Transparent;

            var bgBrush = new SolidBrush(BackgroundColor == Color.Transparent ? ForeColor.GetInverted().ToDrawingColor() : BackgroundColor.ToDrawingColor());
            bmGraphics.FillRectangle(bgBrush, 0, 0, image.Width, image.Height);
            bgBrush.Dispose();

            var left = (Origin == Origin.TopLeft) ? 0 : (Size.Width - textSize.Width) / 2;
            var top = (Origin == Origin.TopLeft) ? 0 : (Size.Height - textSize.Height) / 2;

            bmGraphics.DrawString(Text, Font.FontInformation as Font, sb, left, top);
            sb.Dispose();
            bmGraphics.Dispose();

            return image;
        }

        public void Render(Graphics graphics, int dpi, Location displayOffset, WiMo.Games.Rectangle destRect)
        {
            if (Font.FontInformation == null)
                Font.FontInformation = CreateFont(dpi);

            var image = DrawInformation as Bitmap;

            if (image == null)
                DrawInformation = CreateImage(graphics);

            var targetRect = BoundingRect.GetIntersection(destRect);
            var srcRect = new WiMo.Games.Rectangle(Math.Max(0, destRect.X - BoundingRect.X), Math.Max(0, destRect.Y - BoundingRect.Y), targetRect.Width, targetRect.Height);            

            if (ColorKey == Color.Transparent)
                graphics.DrawImage(DrawInformation as Bitmap, (targetRect + displayOffset).ToDrawingRect(), srcRect.ToDrawingRect(), GraphicsUnit.Pixel);
            else
            {
                var imageAttr = new ImageAttributes();
                imageAttr.SetColorKey(ColorKey.ToDrawingColor(), ColorKey.ToDrawingColor());
                graphics.DrawImage(DrawInformation as Bitmap, (targetRect + displayOffset).ToDrawingRect(), srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, GraphicsUnit.Pixel, imageAttr);
                imageAttr.Dispose();
            }
        }


        public override bool CheckForCollision(ISprite sprite)
        {
            return false;
        }

    }
}
